package cn.dansj.handler.interfaces;

import cn.dansj.annotation.InterfaceParam;
import cn.dansj.annotation.MarkAsApi;
import cn.dansj.bean.CurrentThreadLocalUserInfo;
import cn.dansj.entity.ShortLink;
import cn.dansj.entity.User;
import cn.dansj.enums.GlobalEnv;
import cn.dansj.common.utils.enums.ResponseCode;
import cn.dansj.exception.InterfaceResponseException;
import cn.dansj.service.ShortLinkService;
import cn.dansj.common.context.ApplicationContextProvider;
import cn.dansj.common.redis.RedisUtils;
import cn.dansj.common.utils.transfer.*;
import cn.dansj.handler.InterfaceHandler;

import java.sql.Timestamp;
import java.util.Map;

@SuppressWarnings("all")
@MarkAsApi
public class ShortLinkGenerate extends InterfaceHandler {
    private static final RedisUtils redisUtils = ApplicationContextProvider.getBean(RedisUtils.class);
    private static final ShortLinkService shortLinkService = ApplicationContextProvider.getBean(ShortLinkService.class);
    private static final String prefix = "shortlink@";
    private static final UniqueSequenceUtils uniqueSequenceUtils = UniqueSequenceUtils.getInstance();

    @Override
    @InterfaceParam(value = "link", require = true, comment = "需要转换的链接地址")
    @InterfaceParam(value = "token", require = true, comment = "接口token，个人中心查看获取")
    @InterfaceParam(value = "comment", require = false, comment = "备注信息，个人中心查找显示")
    public Object execute(Map<String, Object> paramsMap) {
        return GlobalEnv.ShortLinkDomain + set(paramsMap.get("link").toString(), Transformation.toString(paramsMap.get("comment")));
    }

    public static String key(String key) {
        return prefix + key;
    }

    public static String set(String url, String comment) {
        final User currentUser = CurrentThreadLocalUserInfo.getCurrentThreadLocalUserInfo().getTokenUser();
        final String sequence = currentUser.getSequence();
        if (Verification.checkNull(sequence)) throw new InterfaceResponseException(ResponseCode.ProjectTokenNotSupport);
        final int userId = Integer.parseInt(sequence);
        if (shortLinkService.countByUserId(userId) >= 50) {
            throw new InterfaceResponseException(ResponseCode.Error.getStatusCode(), "短链接已达上限，请在个人中心删除多余的短链接");
        }
        final ShortLink shortLink = shortLinkService.getUrl(url, userId);

        if (shortLink != null) {
            return shortLink.getShortLink();
        }

        int checkDup = 0;
        boolean dup = false;
        String uid = uniqueSequenceUtils.getUid();
        boolean hasKey = redisUtils.hasKey(key(uid));
        while (hasKey) {
            if (checkDup > 10) {
                dup = true;
                break;
            }
            uid = uniqueSequenceUtils.getUid();
            hasKey = redisUtils.hasKey(key(uid));
            checkDup++;
        }

        if (!dup) {
            ShortLink newShortLink = new ShortLink();
            newShortLink.setShortLink(uid);
            newShortLink.setUserId(userId);
            newShortLink.setUrl(url);
            final Timestamp now = GetTime.dbTimestamp();
            newShortLink.setCreateTime(now);
            newShortLink.setUpdateTime(now);
            newShortLink.setComment(comment);
            newShortLink.setExpireTime(DateTime.getInstance(now.getTime()).addDay(30).toTimestamp());
            final boolean setKey = redisUtils.hmset(key(uid), newShortLink.toJSONObject(), 30 * 24 * 60 * 60);
            if (setKey) {
                try {
                    shortLinkService.save(newShortLink);
                    return uid;
                } catch (Exception exception) {
                    redisUtils.delete(key(uid));
                }
            }
        }
        throw new RuntimeException("短链接生成失败");
    }
}